로딩 중이에요... 🐣
[코담]
웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트
32 2 React & Django 인증 심화 JWT로 안전한 로그인 구현하기 | ✅ 편저: 코담 운영자
🔐 React & Django 인증 심화: JWT로 안전한 로그인 구현하기
이번 포스트에서는 Djoser의 JWT 인증 기능과 React 연동 방법을 집중적으로 다룹니다.
📌 개요
앞선 포스트에서는 Django REST Framework(DRF)와 Djoser로 Token 기반 인증을 설정했습니다. 이번에는 보다 현대적인 방식인 JWT(Json Web Token) 기반 인증을 적용하고, React 프론트엔드에서 이를 활용하는 방법을 알아봅니다.
JWT는 서버의 세션 데이터베이스를 사용하지 않는 stateless 방식으로 인증 성능과 확장성이 뛰어납니다.
6️⃣ JWT 인증 활성화
📁 settings.py
JWT 설정 추가:
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'AUTH_HEADER_TYPES': ('JWT',),
}
DRF의 인증 클래스에서도 JWT를 우선 사용하도록 추가합니다:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
}
📁 urls.py
JWT 인증 URL을 연결합니다.
from django.urls import path, include
urlpatterns = [
path('auth/', include('djoser.urls')),
path('auth/', include('djoser.urls.jwt')),
]
Djoser가 제공하는 JWT 엔드포인트:
auth/jwt/create/
: 로그인 및 JWT 발급auth/jwt/refresh/
: Access Token 갱신auth/jwt/verify/
: JWT 유효성 검증
7️⃣ JWT 인증 API 테스트
📌 JWT 로그인 요청
### JWT 로그인
POST http://localhost:8000/auth/jwt/create/
Content-Type: application/json
{
"username": "admin",
"password": "test"
}
응답
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGci...",
"access": "eyJ0eXAiOiJKV1QiLCJhbGci..."
}
📌 사용자 정보 요청 (JWT 포함)
### JWT로 사용자 정보 조회
GET http://localhost:8000/auth/users/me/
Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGci...
📌 Access Token 갱신
### Access Token Refresh
POST http://localhost:8000/auth/jwt/refresh/
Content-Type: application/json
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGci..."
}
응답
{
"access": "새로운 access token"
}
8️⃣ React와 JWT 연동하기
📁 React 프로젝트 구조
/src/context/AuthContext.js
: 인증 상태 관리/src/services/api.js
: API 요청 처리/src/pages/Login.js
: 로그인 페이지/src/components/PrivateRoute.js
: 보호된 라우트
🛠 AuthContext 구현
import React, { createContext, useState } from 'react';
import axios from 'axios';
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [authTokens, setAuthTokens] = useState(() =>
JSON.parse(localStorage.getItem('authTokens'))
);
const loginUser = async (username, password) => {
const response = await axios.post('/auth/jwt/create/', {
username,
password,
});
if (response.status === 200) {
setAuthTokens(response.data);
localStorage.setItem('authTokens', JSON.stringify(response.data));
}
};
const logoutUser = () => {
setAuthTokens(null);
localStorage.removeItem('authTokens');
};
return (
<AuthContext.Provider value={{ authTokens, loginUser, logoutUser }}>
{children}
</AuthContext.Provider>
);
};
export default AuthContext;
🔒 PrivateRoute 구성
import { Navigate } from 'react-router-dom';
import { useContext } from 'react';
import AuthContext from '../context/AuthContext';
const PrivateRoute = ({ children }) => {
const { authTokens } = useContext(AuthContext);
return authTokens ? children : <Navigate to="/login" />;
};
export default PrivateRoute;
📥 API 요청 시 토큰 추가
import axios from 'axios';
const api = axios.create({
baseURL: 'http://localhost:8000',
});
api.interceptors.request.use((config) => {
const tokens = JSON.parse(localStorage.getItem('authTokens'));
if (tokens) {
config.headers.Authorization = `JWT ${tokens.access}`;
}
return config;
});
export default api;
다음 포스트에서는 React에서 토큰 갱신 로직, 로그아웃 처리 및 인증 보호된 페이지 구현을 심화하여 다룹니다.